package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterEventData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.manager.EventConvert;
import com.navinfo.platform.trip.common.arithmetic.var.VarIdleParking;
import com.navinfo.platform.trip.common.arithmetic.enums.EventStatus;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;

import java.util.Optional;

/**
 * 东风超长怠速算法<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 */
public class IdleLong_DF extends AbstractArithmetic<VarIdleParking> {
    /**
     * 事件类型
     */
    private static final EventType event = EventType.idleLong_DF;
    /**
     * 超长怠速算法 转速阀值 单位：rpm
     */
    private long rotationThreshold = ConfigMap.getInteger("DF_LongIdle_Rotation_Threshold");
    /**
     * 超长怠速算法 时间阀值 单位：s，默认600s，10分钟
     */
    private long timeThreshold = ConfigMap.getInteger("DF_LongIdle_Time_Threshold");

    /**
     * 判断当前点是否为怠速状态
     * 引擎转速>0,并且车速=0
     */
    public boolean isCurParkingIdle() {
        CommonData data = drivingData.getCommonData();
        // 怠速状态判定：引擎转速>500 and 车速==0
        return (data.getRotation() > rotationThreshold && data.getSpeedKmh() == 0);
    }

    @Override
    public void calculate() {
        logger.debug("进入东风超长怠速算法.[terminalId:{}]", terminalId);
        VarIdleParking var = getObj();

        boolean previousIdle = var.isPreParkingIdle();
        boolean currentIdle = isCurParkingIdle();
        var.setPreParkingIdle(currentIdle);
        logger.debug("东风超长怠速算法，怠速状态：previousIdle:{},currentIdle:{}.[terminalId:{}]", previousIdle, currentIdle, terminalId);

        //算法计算
        EventStatus eventStatus = super.getEventStatus(previousIdle, currentIdle);
        switch (eventStatus) {
            case START:
                logger.debug("东风超长怠速算法，事件开始.[terminalId:{}]", terminalId);
                startEventData(event);
                break;
            case IN:
                logger.debug("东风超长怠速算法，事件中.[terminalId:{}]", terminalId);
                calcEventData(event);
                break;
            case END:
                logger.debug("东风超长怠速算法，事件结束.[terminalId:{}]", terminalId);
                calcEventData(event);
                endEventData();
                break;
            default:
                logger.debug("东风超长怠速算法，怠速状态：上一次和本次都未怠速，跳出算法.[terminalId:{}]", terminalId);
        }

        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEventData();
        }

        logger.debug("东风超长怠速算法结束.[terminalId:{}]", terminalId);
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarIdleParking var = getObj();
        statisticDataOut.setLongIdleNumber_DF(var.getNumber());
        statisticDataOut.setLongIdleFuel_DF(ArithmeticUtils.fuelMlToMl(var.getFuel()));
        statisticDataOut.setLongIdleDuration_DF(ArithmeticUtils.timeMsToSecond(var.getTimeMs()));
    }


    /**
     * 处理事件的结束状态
     */
    private void endEventData() {
        Optional.ofNullable(drivingData.getEventData(event)).ifPresent(eventData -> {
            EventConvert.convertEnd(eventData, drivingData);
            drivingData.removeEventData(event);

            //怠速时长大于10分钟；
            if (Optional.ofNullable(eventData.getDuration()).orElse(0L) >= timeThreshold*1000) {
                logger.debug("东风超长怠速时间{}ms,进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L));

                //事件结束，累加统计数据
                eventDataToVar(eventData);

                //放入输出事件列表
                drivingData.addEventDataToList(eventData);
            } else {
                logger.debug("东风超长怠速时间{}ms,小于阈值{}ms，不进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L), timeThreshold);
            }
        });
    }

    /**
     * 事件数据累加到统计数据中
     */
    private void eventDataToVar(OuterEventData eventData){
        VarIdleParking var = getObj();
        var.setNumber(var.getNumber()+1);
        var.setFuel(var.getFuel()+  Optional.ofNullable(eventData.getExtendField06()).orElse(0.0));
        var.setTimeMs(var.getTimeMs() + Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());
    }
}
